package org.dromara.hotel.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.dromara.common.core.utils.SpringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hotel.domain.TerHotelRooms;
import org.dromara.hotel.domain.TerPricingRule;
import org.dromara.hotel.domain.vo.TerPriceCalendarVo;
import org.dromara.hotel.dubbo.RemoteFullSyncServiceImpl;
import org.dromara.hotel.mapper.TerHotelRoomsMapper;
import org.dromara.hotel.mapper.TerPricingRuleMapper;
import org.dromara.hotel.service.ITerPricingRuleService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.dromara.hotel.service.ITerHotelInventoryService;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 房态Service业务层处理
 *
 * @author xch
 * @date 2025-06-12
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class TerHotelInventoryServiceImpl implements ITerHotelInventoryService {

    private final RedisTemplate<String, String> redisTemplate;
    private final RemoteFullSyncServiceImpl remoteFullSyncService;

    private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);


    @Override
    // 原子化库存扣减
    public boolean deductInventory(Long roomTypeId, LocalDate date, int quantity) {
        String key = remoteFullSyncService.buildInventoryKey(roomTypeId, date);
        RLock lock = CLIENT.getLock(key + ":rollback_lock"); // 回滚专用锁
        try {
            Long remaining = redisTemplate.opsForValue().decrement(key, quantity);
            if (remaining != null && remaining >= 0) {
                return true;
            } else {
                // 加锁保证回滚原子性
                if (lock.tryLock(3, 10, TimeUnit.SECONDS)) {
                    redisTemplate.opsForValue().increment(key, quantity);
                }
                return false;
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }


}
